<template>
  <div class="views" id="views" @touchmove.prevent @mousewheel.prevent>
    <div id="containerTorch" class="container"></div>
  </div>
</template>

<script>
import * as THREE from 'three/build/three.module'
import { ThreeJsUtil } from '@/assets/ThreeJsUtil/ThreeJsUtil'
import { MqttUtil } from '@/utils/MqttUtil'

const threeApp = new ThreeJsUtil()
export default {
  props: ['home'],
  data () {
    return {
      params: {
        methods: {
          animation: false,
          renderer: true,
          light: true,
          controls: true,
          TWEEN: true,
          postprocessing: true,
          statement: true
        },
        events: {
          windowResize: true
        },
        params: {
          containerId: 'containerTorch',
          renderer: [
            'WebGLRenderer'
          ],
          controls: [
            'OrbitControls'
          ],
          rendererParams: {
            antialias: true
          },
          postprocessing: [
            'OutlinePass',
            // 'UnrealBloomPass'
          ]
        }
      },
      topics: {
        pcj: `${this.$route.path}_position-controls-json`,
        soj: `${this.$route.path}_select-objName-json`,
        poj: `${this.$route.path}_perform-objName-json`
      },
      routerName: this.$route.name
    }
  },
  mounted () {
    this.home.loading()
    /**
     * 初始化场景
     */
    threeApp.init(this.params, (scene, camera, renderer) => {
      // 添加天空盒
      // scene.background = new THREE.CubeTextureLoader()
      //   .setPath('static/model/img/skybox2/')
      //   .load(['right.png', 'left.png', 'top.png', 'bottom.png', 'back.png', 'front.png']) // 右左上下后前
      scene.background = new THREE.CubeTextureLoader()
        .setPath('static/model/img/skybox2/')
        .load(['RT.jpg', 'LF.jpg', 'UP.jpg', 'DN.jpg', 'BK.jpg', 'FR.jpg']) // 右左上下后前

      // 重设相机初始位置
      camera.position.set(-1000, 300, 1000)

      // 设置相机俯仰视角范围
      threeApp.orbitControls.minPolarAngle = 0
      threeApp.orbitControls.maxPolarAngle = Math.PI / 2
      threeApp.orbitControls.autoRotate = false

      // // 设置辉光参数
      // threeApp.unrealBloomPass.threshold = 0
      // threeApp.unrealBloomPass.strength = 0.5
      // threeApp.unrealBloomPass.radius = 0
    })

    threeApp.addModel({
      url: 'static/model/fbx/torch/torch.FBX',
      type: 'fbx',
      name: 'torch'
    }, (obj) => {
      this.home.loadOver()
      // function getLabelPosition (obj) {
      //   var box = new THREE.Box3()
      //   var expand = box.expandByObject(obj)
      //   var h = (expand.max.y - expand.min.y) / 2
      //   const center = threeApp.getObjWorldPosition(obj)
      //   return [center.x, center.y + (h * 1.5), center.z]
      // }
      // obj.traverse((child) => {
      //   switch (child.name) {
      //     case 'Group1871025528': // 教学楼
      //       threeApp.createSpriteText('教学楼', {
      //         fontSize: 20,
      //         // backgroundColor: '#f80b0b', // 背景颜色，默认为透明transparent
      //         color: '#04eef6', // 字体颜色
      //         scale: [50, 10, 1], // 标签缩放比例，参数分别为x,y,z
      //         position: getLabelPosition(child) // 标签所在位置，参数分别为x,y,z
      //       })
      //       break
      //     case 'Group1871025524': // 综合楼
      //       threeApp.createSpriteText('综合楼', {
      //         fontSize: 20,
      //         // backgroundColor: '#f80b0b', // 背景颜色，默认为透明transparent
      //         color: '#04eef6', // 字体颜色
      //         scale: [50, 10, 1], // 标签缩放比例，参数分别为x,y,z
      //         position: getLabelPosition(child) // 标签所在位置，参数分别为x,y,z
      //       })
      //       break
      //     case 'Group015': // 幼儿园
      //       threeApp.createSpriteText('幼儿园', {
      //         fontSize: 20,
      //         // backgroundColor: '#f80b0b', // 背景颜色，默认为透明transparent
      //         color: '#04eef6', // 字体颜色
      //         scale: [50, 10, 1], // 标签缩放比例，参数分别为x,y,z
      //         position: getLabelPosition(child) // 标签所在位置，参数分别为x,y,z
      //       })
      //       break
      //     case 'Group1871025505': // 操场
      //       threeApp.createSpriteText('操场', {
      //         fontSize: 20,
      //         // backgroundColor: '#f80b0b', // 背景颜色，默认为透明transparent
      //         color: '#04eef6', // 字体颜色
      //         scale: [50, 10, 1], // 标签缩放比例，参数分别为x,y,z
      //         position: getLabelPosition(child) // 标签所在位置，参数分别为x,y,z
      //       }).position.y += 10
      //       break
      //     case 'Group1871025500': // 篮球场
      //       threeApp.createSpriteText('篮球场', {
      //         fontSize: 20,
      //         // backgroundColor: '#f80b0b', // 背景颜色，默认为透明transparent
      //         color: '#04eef6', // 字体颜色
      //         scale: [50, 10, 1], // 标签缩放比例，参数分别为x,y,z
      //         position: getLabelPosition(child) // 标签所在位置，参数分别为x,y,z
      //       })
      //       break
      //     case 'Group1871025501': // 篮球场（单）
      //       threeApp.createSpriteText('篮球场', {
      //         fontSize: 20,
      //         // backgroundColor: '#f80b0b', // 背景颜色，默认为透明transparent
      //         color: '#04eef6', // 字体颜色
      //         scale: [50, 10, 1], // 标签缩放比例，参数分别为x,y,z
      //         position: getLabelPosition(child) // 标签所在位置，参数分别为x,y,z
      //       })
      //       break
      //     case 'Plane006': // 操场（小）
      //       threeApp.createSpriteText('操场', {
      //         fontSize: 20,
      //         // backgroundColor: '#f80b0b', // 背景颜色，默认为透明transparent
      //         color: '#04eef6', // 字体颜色
      //         scale: [25, 5, 1], // 标签缩放比例，参数分别为x,y,z
      //         position: getLabelPosition(child) // 标签所在位置，参数分别为x,y,z
      //       }).position.y += 5
      //       break
      //     case 'Group1871025504': // 羽毛球场
      //       threeApp.createSpriteText('羽毛球场', {
      //         fontSize: 20,
      //         // backgroundColor: '#f80b0b', // 背景颜色，默认为透明transparent
      //         color: '#04eef6', // 字体颜色
      //         scale: [25, 5, 1], // 标签缩放比例，参数分别为x,y,z
      //         position: getLabelPosition(child) // 标签所在位置，参数分别为x,y,z
      //       })
      //   }
      // })
      // 相机飞行
      if (this.home.mqttForm.status !== 'sub' || !this.mqtt) {
        threeApp.flyTo({
          position: [50.5, 42, -150],
          controls: [25, 3, 0],
          duration: 3000
        })
      }

      // 添加双击事件
      threeApp.addOn(threeApp.scene, 'dblclick', (objList) => {
        const obj = objList[0].object

        this.performEvent(obj)
        // console.log(obj.name, obj.parent.name)
      }, 'dblclick_torch', {
        recursive: true
      })

      // 添加鼠标移动事件
      threeApp.addOn(threeApp.scene, 'mousemove', (objList) => {
        const obj = objList[0].object

        this.selectEvent(obj)
        // threeApp.outlinePass.selectedObjects = [obj]
      }, 'mousemove_torch', {
        recursive: true
      }, () => {
        threeApp.outlinePass.selectedObjects = []
        this.curentObjName = null
        this.curentGroupName = null
        this.curentGroupParentName = null
        this.mqttPubSelectObjName('null')
      })

      // 添加触摸事件
      threeApp.addOn(threeApp.scene, 'touchstart', (objList) => {
        const obj = objList[0].object
        const group = obj.parent

        if (obj.name === this.curentObjName || group.name === this.curentGroupName || group.parent.name === this.curentGroupParentName) { // 判断为双击
          this.performEvent(obj)
        } else { // 判断为单击
          this.selectEvent(obj)
        }
      }, 'touchstart_torch', { recursive: true }, () => {
        threeApp.outlinePass.selectedObjects = []
        this.curentObjName = null
        this.curentGroupName = null
        this.curentGroupParentName = null
        this.mqttPubSelectObjName('null')
      })
    }, (progress) => {
      progress = parseInt((progress.loaded / progress.total) * 100)
      this.home.loadProgress(progress)
    })

    threeApp.animate(() => {
      this.mqttPubPositionControls()
    })
    this.mqttInit()
  },
  methods: {
    mqttInit () {
      if (this.home.mqttForm.status === 'sub') {
        if (this.mqtt) this.mqtt.client.end()
        this.mqtt = new MqttUtil(`mqtt://${this.home.mqttForm.url}`, { clientId: `${this.$route.name}_${this.home.mqttForm.status}` })
        this.mqtt.setSubTopic(this.topics.pcj)
        this.mqtt.setSubTopic(this.topics.soj)
        this.mqtt.setSubTopic(this.topics.poj)
        this.mqttSubInit()
        this.mqtt.subTopic(this.mqttSub)
      } else if (this.home.mqttForm.status === 'pub') {
        if (this.mqtt) this.mqtt.client.end()
        this.mqtt = new MqttUtil(`mqtt://${this.home.mqttForm.url}`, { clientId: `${this.$route.name}_${this.home.mqttForm.status}` })
      } else if (this.home.mqttForm.status === 'alone') {
        if (this.mqtt) this.mqtt.client.end()
        this.mqttSubDestroy()
      }
    },
    mqttSubInit () {
      threeApp.orbitControls.enabled = false
    },
    mqttSub (topic, message) {
      message = JSON.parse(message.toString())
      if (topic === this.topics.pcj && message) {
        threeApp.camera.position.set(...message.position)
        threeApp.camera.lookAt(...message.controls)
      } else if (topic === this.topics.soj && message) {
        if (message.objName !== 'null') {
          const obj = threeApp.scene.getObjectByName(message.objName)
          this.selectEvent(obj)
        } else {
          threeApp.outlinePass.selectedObjects = []
        }
      } else if (topic === this.topics.poj && message) {
        const obj = threeApp.scene.getObjectByName(message.objName)
        this.performEvent(obj)
      }
    },
    mqttSubDestroy () {
      threeApp.orbitControls.enabled = true
    },
    mqttPubPositionControls () {
      if (this.home.mqttForm.status !== 'pub' || !this.mqtt || this.$route.name !== this.routerName) return
      const controls = [threeApp.orbitControls.target.x, threeApp.orbitControls.target.y, threeApp.orbitControls.target.z]
      const position = [threeApp.camera.position.x, threeApp.camera.position.y, threeApp.camera.position.z]

      const message = JSON.stringify({
        position,
        controls
      })
      if (this.nextPCMessage === message) return
      this.nextPCMessage = message
      this.mqtt.pubTopic(this.topics.pcj, message)
    },
    mqttPubSelectObjName (objName) {
      if (this.home.mqttForm.status !== 'pub' || !this.mqtt || this.$route.name !== this.routerName) return
      const message = JSON.stringify({
        objName
      })
      this.mqtt.pubTopic(this.topics.soj, message)
    },
    mqttPubPerformObjName (objName) {
      if (this.home.mqttForm.status !== 'pub' || !this.mqtt || this.$route.name !== this.routerName) return
      const message = JSON.stringify({
        objName
      })
      this.mqtt.pubTopic(this.topics.poj, message)
    },
    selectEvent (obj) {
      switch (obj.name) {
        case 'Line733': // 篮球场（单）
          threeApp.outlinePass.selectedObjects = [obj]
          this.curentObjName = obj.name
          this.mqttPubSelectObjName(obj.name)
          return
      }
      const group = obj.parent
      switch (group.name) {
        // case 'Group1871025522': // 教学楼
        // case 'Group1871025520': // 综合楼
        // case 'Group1871025521': // 幼儿园
        case 'Group1871025505': // 操场
        case 'Group1871025678': // 篮球场
        // case 'Group1871025501': // 篮球场（单）
        case 'Plane006': // 操场（小）
        case 'Group1871025504': // 羽毛球场
          threeApp.outlinePass.selectedObjects = [group]
          this.curentGroupName = group.name
          this.mqttPubSelectObjName(obj.name)
          return
        // break
        // default:
        //   threeApp.outlinePass.selectedObjects = []
        //   this.curentObjName = null
        //   if (this.home.mqttForm.status === 'pub' && this.mqtt) this.mqttPubOutlineObjName('null')
      }
      switch (group.parent.name) {
        case 'Group1871025528': // 教学楼
        case 'Group1871025524': // 综合楼
        case 'Group015': // 幼儿园
          threeApp.outlinePass.selectedObjects = [group.parent]
          this.curentGroupParentName = group.parent.name
          this.mqttPubSelectObjName(obj.name)
          return
        // break
      }
      threeApp.outlinePass.selectedObjects = []
      this.curentObjName = null
      this.curentGroupName = null
      this.curentGroupParentName = null
      this.mqttPubSelectObjName('null')
    },
    performEvent (obj) {
      threeApp.outlinePass.selectedObjects = []
      this.curentObjName = null
      this.curentGroupName = null
      this.curentGroupParentName = null
      this.mqttPubSelectObjName('null')
      switch (obj.name) {
        case 'Line733': // 篮球场（单）
          threeApp.flyToObj(obj, {
            vector: new THREE.Vector3(0.7, 0.7, 0.7),
            flyToOption: { duration: 1000 }
          })
          return
      }
      const group = obj.parent
      switch (group.name) {
        // case 'Group1871025522': // 教学楼
        //   this.$router.push('jxl')
        //   this.home.tierChange('jxl')
        //   if (this.home.mqttForm.status === 'pub' && this.mqtt) this.mqttPubPathTierName('jxl', 'jxl')
        //   break
        // case 'Group1871025520': // 综合楼
        //   this.$router.push('zhl')
        //   this.home.tierChange('zhl')
        //   if (this.home.mqttForm.status === 'pub' && this.mqtt) this.mqttPubPathTierName('zhl', 'zhl')
        //   break
        // case 'Group1871025521': // 幼儿园
        //   this.$router.push('yry')
        //   this.home.tierChange('yry')
        //   if (this.home.mqttForm.status === 'pub' && this.mqtt) this.mqttPubPathTierName('yry', 'yry')
        //   break
        case 'Group1871025505': // 操场
        case 'Group1871025678': // 篮球场
        // case 'Group1871025501': // 篮球场（单）
        case 'Plane006': // 操场（小）
        case 'Group1871025504': // 羽毛球场
          threeApp.flyToObj(group, {
            vector: new THREE.Vector3(0.7, 0.7, 0.7),
            flyToOption: { duration: 1000 }
          })
          return
      }
      switch (group.parent.name) {
        case 'Group1871025528': // 教学楼
          this.$router.push('jxl')
          this.home.tierChange('jxl')
          this.mqttPubPerformObjName(obj.name)
          return
        case 'Group1871025524': // 综合楼
          this.$router.push('zhl')
          this.home.tierChange('zhl')
          this.mqttPubPerformObjName(obj.name)
          return
        case 'Group015': // 幼儿园
          this.$router.push('yry')
          this.home.tierChange('yry')
          this.mqttPubPerformObjName(obj.name)
          return
      }
    }
  },
  beforeDestroy () {
    threeApp.rmOn('dblclick', 'dblclick_torch')
    threeApp.rmOn('mousemove', 'mousemove_torch')
    threeApp.rmOn('touchstart', 'touchstart_torch')
    threeApp.destroy()
    if (this.mqtt) this.mqtt.client.end()
  }
}
</script>

<style scoped>
.views {
  height: 100%;
  width: 100%;
}

.container {
  height: 100%;
  width: 100%;
}
</style>
